import { BorderType } from "./borderType";
import { boxFilterImageData } from "./boxFilterImageData";
import { boxFilterUint8 } from "./boxFilterUint8";
import { boxFilterArray } from "./boxFilterArray";

/**
 * 生成测试用2D数组
 */
function generateTestArray(width: number, height: number): number[][] {
  const arr: number[][] = [];
  for (let y = 0; y < height; y++) {
    const row: number[] = [];
    for (let x = 0; x < width; x++) {
      row.push(Math.random() * 255);
    }
    arr.push(row);
  }
  return arr;
}

/**
 * 生成测试用Uint8ClampedArray（确保使用标准ArrayBuffer）
 */
function generateTestUint8(width: number, height: number): Uint8ClampedArray {
  const size = width * height * 4;
  // 明确使用ArrayBuffer创建，避免类型歧义
  const buffer = new ArrayBuffer(size);
  const data = new Uint8ClampedArray(buffer);

  for (let i = 0; i < size; i += 4) {
    data[i] = Math.random() * 255; // R
    data[i + 1] = Math.random() * 255; // G
    data[i + 2] = Math.random() * 255; // B
    data[i + 3] = 255; // A
  }
  return data;
}

/**
 * 基准测试ImageData滤波性能
 */
export function benchmarkImageData(
  width: number = 1920,
  height: number = 1080,
  radius: number = 5,
  iterations: number = 10,
): number {
  const data = generateTestUint8(width, height);
  // 明确类型断言，帮助TypeScript识别正确类型
  const imageData = new ImageData(data as ImageDataArray, width, height);

  const start = performance.now();

  for (let i = 0; i < iterations; i++) {
    const filteredImageData = boxFilterImageData(imageData, {
      radius,
      borderType: BorderType.REPLICATE,
    });

    // 验证 filteredImageData 是否符合预期
    if (
      !(filteredImageData.data instanceof Uint8ClampedArray) ||
      !(filteredImageData.data.buffer instanceof ArrayBuffer)
    ) {
      throw new TypeError(
        "Filtered image data is not a valid Uint8ClampedArray with ArrayBuffer",
      );
    }
  }

  const end = performance.now();
  return (end - start) / iterations;
}

/**
 * 基准测试Uint8ClampedArray滤波性能
 */
export function benchmarkUint8(
  width: number = 1920,
  height: number = 1080,
  radius: number = 5,
  iterations: number = 10,
): number {
  const data = generateTestUint8(width, height);

  const start = performance.now();

  for (let i = 0; i < iterations; i++) {
    // 每次迭代使用数据副本
    const copy = new Uint8ClampedArray(data);
    boxFilterUint8(copy, width, height, radius);
  }

  const end = performance.now();
  return (end - start) / iterations;
}

/**
 * 基准测试2D数组滤波性能
 */
export function benchmarkArray(
  width: number = 1920,
  height: number = 1080,
  radius: number = 5,
  iterations: number = 10,
): number {
  const data = generateTestArray(width, height);

  const start = performance.now();

  for (let i = 0; i < iterations; i++) {
    boxFilterArray(data, { radius });
  }

  const end = performance.now();
  return (end - start) / iterations;
}

/**
 * 运行所有基准测试并输出结果
 */
export function runAllBenchmarks(): void {
  console.log("Running benchmarks...");
  console.log("Image size: 1920x1080, radius: 5, iterations: 10");

  const arrayTime = benchmarkArray();
  console.log(`2D Array average time: ${arrayTime.toFixed(2)}ms`);

  const imageDataTime = benchmarkImageData();
  console.log(`ImageData average time: ${imageDataTime.toFixed(2)}ms`);

  const uint8Time = benchmarkUint8();
  console.log(`Uint8ClampedArray average time: ${uint8Time.toFixed(2)}ms`);

  console.log(
    `Performance ratio (Array/Uint8): ${(arrayTime / uint8Time).toFixed(1)}x`,
  );
}
